package com.szly.phm.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.szly.phm.common.entity.dto.system.SysMessagePageDTO;
import com.szly.phm.common.entity.dto.user.*;
import com.szly.phm.common.entity.po.*;
import com.szly.phm.common.entity.result.CodeStatusEnum;
import com.szly.phm.common.entity.result.PageResult;
import com.szly.phm.common.entity.result.RootResponse;
import com.szly.phm.common.entity.vo.user.UserPageVO;
import com.szly.phm.common.mapper.*;
import com.szly.phm.common.service.ISysUserService;
import com.szly.phm.common.utils.BeanCopyUtils;
import com.szly.phm.common.utils.HandleUtils;
import com.szly.phm.common.utils.SHA256Utils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author admin
 * @since 2021-07-02
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    private final SysRoleMapper roleMapper;
    private final RaServerAreaMapper raServerAreaMapper;
    private final SysUserRoleMapper userRoleMapper;

    private final SysUserMapper sysUserMapper;
    private final SysMessageMapper sysMessageMapper;
    private final SysMessageProcessMapper sysMessageProcessMapper;
    @Value("${com.jejl.login.enableUniversalPassword}")
    private boolean enableUniversalPassword;

    @Value("${com.jejl.login.universalPassword}")
    private String universalPassword;
    @Override
    public SysUser queryUserByUsername(String username) {
        var wrapper = new LambdaQueryWrapper<SysUser>();
        wrapper.eq(SysUser::getIsSoftDelete, false);
        wrapper.eq(SysUser::getUsername, username);
        var user = baseMapper.selectOne(wrapper);
        return user;
    }

    @Override
    public RootResponse createUser(CreateUserDTO userDTO, LoginUserDTO loginDTO) {
//        var root = this.isPassword(userDTO.getPassword());
//        if (!CodeStatusEnum.SUCCESS.getCode().equals(root.getCode())) {
//            return root;
//        }
        SysUser user = null;
        try {
            user = baseMapper.selectUserByUserName(userDTO.getUsername());
            if (user != null) {
                return RootResponse.error(CodeStatusEnum.EXIST_USERNAME);
            }
            user = baseMapper.selectUserByMobile(userDTO.getMobile());
            if (user != null) {
                return RootResponse.error(CodeStatusEnum.EXIST_MOBILE);
            }
            user = baseMapper.selectUserByMailbox(userDTO.getMailbox());
            if (user != null) {
                return RootResponse.error(CodeStatusEnum.EXIST_Mailbox);
            }
            user = baseMapper.selectUserByCertificatesId(userDTO.getCertificatesId());
            if (user != null) {
                return RootResponse.error(CodeStatusEnum.EXIST_CertificatesId);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return RootResponse.error("数据异常，可能存在多条重名或重复手机号用户");
        }
        user = new SysUser();
        this.handleUserData(userDTO, user, loginDTO);
        var i = baseMapper.insert(user);
        if (i != 1) {
            return RootResponse.error();
        }
//        this.addUserRole(userDTO.getRoleId(), user.getId());
        return RootResponse.success(user);
    }


    @Override
    public RootResponse updateUser(UpdateUserDTO updateUserDTO, LoginUserDTO loginDTO) {
        var user = baseMapper.selectById(updateUserDTO.getId());
        if (user == null || user.getIsSoftDelete()) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        try {

            //不允许手机号重复
            if (user.getMobile()!=null&&!user.getMobile().equals(updateUserDTO.getMobile())) {
                var uu = baseMapper.selectUserByMobile(updateUserDTO.getMobile());
                if (uu != null) {
                    return RootResponse.error(CodeStatusEnum.EXIST_MOBILE);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return RootResponse.error("999", "数据异常，可能存在多条重名或重复手机号用户");
        }
//        var password = user.getPassword();
        BeanCopyUtils.copy(updateUserDTO, user);
//        user.setPassword(password);
//        if (!"********".equals(updateUserDTO.getPassword())) {
//            var root = this.isPassword(updateUserDTO.getPassword());
//            if (!CodeStatusEnum.SUCCESS.getCode().equals(root.getCode())) {
//                return root;
//            }
//            var str = new StringBuilder();
//            var salt = HandleUtils.getRandomString(32);
//            str = str.append(updateUserDTO.getPassword()).append(salt);
//            var pSHA256 = SHA256Utils.SHA256(str.toString());
//            user.setPassword(pSHA256);
//            user.setSalt(salt);
//        }
        user.setUpdater(loginDTO.getUsername());
        user.setUpdateDateTime(new Date());
        int i = baseMapper.updateById(user);
        if (i != 1) {
            return RootResponse.error();
        }
//        checkUserRole(updateUserDTO.getRoleId(), updateUserDTO.getId());

        return RootResponse.success(user);
    }

    @Override
    public RootResponse updateHeaderName(UpdateUserHeaderDTO updateUserDTO, LoginUserDTO loginDTO) {
        var user = baseMapper.selectById(loginDTO.getUserId());
        if (user == null || user.getIsSoftDelete()) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        BeanCopyUtils.copy(updateUserDTO, user);
        user.setUpdater(loginDTO.getUsername());
        user.setUpdateDateTime(new Date());
        int i = baseMapper.updateById(user);
        if (i != 1) {
            return RootResponse.error();
        }
        return RootResponse.success("修改成功");
    }




    private void checkUserRole(String roleIds, String userId) {
        var qWrapper = new LambdaQueryWrapper<SysUserRole>();
        qWrapper.eq(SysUserRole::getUserId, userId);
        var list = userRoleMapper.selectList(qWrapper);
        var ids = roleIds.split(",");
        if (ids.length != list.size()) {
            userRoleMapper.delete(qWrapper);
            this.addUserRole(roleIds, userId);
        }
        for (int i = 0; i < ids.length; i++) {
            var lids = list.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
            if (!lids.contains(ids[i])) {
                userRoleMapper.delete(qWrapper);
                this.addUserRole(roleIds, userId);
                break;
            }
        }
    }

    @Override
    public RootResponse deleteUser(String id, LoginUserDTO loginDTO) {
        var user = baseMapper.selectById(id);
        if (user == null || user.getIsSoftDelete()) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        user.setUpdateDateTime(new Date());
        user.setUpdater(loginDTO.getUsername());
        user.setIsSoftDelete(true);
        int i = baseMapper.updateById(user);
        if (i != 1) {
            return RootResponse.error();
        }
        // 删除用户与角色的关联关系
        var qWrapper = new LambdaQueryWrapper<SysUserRole>();
        qWrapper.eq(SysUserRole::getUserId, id);
        userRoleMapper.delete(qWrapper);
        return RootResponse.success(user);
    }

    @Override
    public RootResponse<PageResult<UserPageVO>> queryUserPage(UserPageDTO userPageDTO) {
        PageHelper.startPage(userPageDTO.getPageNum(), userPageDTO.getPageSize());
        var users = baseMapper.selectUsersPage(userPageDTO);
        var newList = new ArrayList<UserPageVO>();
        var pageInfo = PageInfo.of(users);
        if (HandleUtils.ListIsNotNull(users)) {
            users.forEach(m -> {
                var user = new UserPageVO();
               var area= raServerAreaMapper.selectById(m.getAreaId());
                BeanCopyUtils.copy(m, user);
                user.setPassword("********");
                user.setAreaName(area==null?null:area.getName());
//                var roles = roleMapper.queryRolesByUserId(m.getId());
//                if (roles != null) {
//                    var userRoles = new ArrayList<UserRoleVO>();
//                    roles.forEach(r -> {
//                        var userRole = new UserRoleVO();
//                        userRole.setRoleId(r.getId());
//                        userRole.setRoleName(r.getRoleName());
//                        userRoles.add(userRole);
//                    });
//                    user.setRoles(userRoles);
//                }
                newList.add(user);
            });
        }
        return RootResponse.success(PageResult.page(newList, pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal()));
    }

    @Override
    public RootResponse queryUserLongin(VerificationUserDTO verificationUserDTO) {
        var user = baseMapper.selectUserByUserName(verificationUserDTO.getUsername());
        if (user == null || user.getIsSoftDelete()) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        //万能密码
        if (!(enableUniversalPassword && universalPassword.equals(verificationUserDTO.getPassword()))) {
            //密码验证
            var str = new StringBuilder();
            str = str.append(verificationUserDTO.getPassword()).append(user.getSalt());
            var pSHA256 = SHA256Utils.SHA256(str.toString());
            if (!user.getPassword().equals(pSHA256)) {
//                    loginLog.setLoginState("01");
//                    loginLog.setLoginInfo(CodeStatusEnum.WRONG_PASSWORD.getMessage());
//                    logAsync.addLoginLog(loginLog);
              return  RootResponse.error("密码错误");
            }
        }
return  RootResponse.success();
    }

    @Override
    public RootResponse resetPassword(String userId, LoginUserDTO loginDTO) {
        var user = baseMapper.selectById(userId);
        if (user == null || user.getIsSoftDelete()) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        var str = new StringBuilder();
        var salt = HandleUtils.getRandomString(32);
        var password = "123456";
        str = str.append(password).append(salt);
        var pSHA256 = SHA256Utils.SHA256(str.toString());
        user.setPassword(pSHA256);
        user.setSalt(salt);
        user.setUpdater(loginDTO.getUsername());
        user.setUpdateDateTime(new Date());
        var i = baseMapper.updateById(user);
        return i == 1 ? RootResponse.success(password) : RootResponse.error();
    }

    @Override
    public RootResponse updatePassword(UpdatePasswordDTO passwordDTO, LoginUserDTO loginDTO) {
        var root = isPassword(passwordDTO.getNewPassword());
        if (!CodeStatusEnum.SUCCESS.getCode().equals(root.getCode())) {
            return root;
        }
        if (!passwordDTO.getNewPassword().equals(passwordDTO.getConfirmPassword())) {
            return RootResponse.error(CodeStatusEnum.DIFFERENT_PASSWORD);
        }
        var user = baseMapper.selectById(loginDTO.getUserId());
        if (user == null || user.getIsSoftDelete()) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        var str = new StringBuilder();
        str = str.append(passwordDTO.getOldPassword()).append(user.getSalt());
        var oldSHA256 = SHA256Utils.SHA256(str.toString());//加密后的旧密码
        if (!oldSHA256.equals(user.getPassword())) {
            return RootResponse.error(CodeStatusEnum.WRONG_OLD_PASSWORD);
        }
        var secretKey = HandleUtils.getRandomString(32);//重新生成密文
        user.setSalt(secretKey);
        var sb = new StringBuilder();
        sb = sb.append(passwordDTO.getNewPassword()).append(secretKey);
        user.setPassword(SHA256Utils.SHA256(sb.toString()));
        int i = baseMapper.updateById(user);
        if (i != 1) {
            return RootResponse.error();
        }
        return RootResponse.success(user);
    }


    private void addUserRole(String roleId, String userId) {
        if (StringUtils.isNotBlank(roleId)) {
            var arr = roleId.split(",");
            if (arr != null && arr.length > 0) {
                for (var id : arr) {
                    var userRole = new SysUserRole();
                    userRole.setId(HandleUtils.UUID32());
                    userRole.setUserId(userId);
                    userRole.setRoleId(id);
                    int j = userRoleMapper.insert(userRole);
                    if (j != 1) {
                        throw new RuntimeException("给用户分配角色失败");
                    }
                }
            }
        }
    }



    // 验证密码强度
    private RootResponse isPassword(String password) {
        if (password.length() < 6 || password.length() > 16) {
            return RootResponse.error(CodeStatusEnum.FAIL.getCode(), "密码长度为6到16位");
        }
        if (!(password.matches(".*[a-z]{1,}.*") && password.matches(".*[A-Z]{1,}.*") && password.matches(".*\\d{1,}.*") && password.matches(".*[~!@#$%^&*\\.?]{1,}.*"))) {
            return RootResponse.error(CodeStatusEnum.FAIL.getCode(), "密码需包含大写字母、小写字母、数字以及特殊字符(~!@#$%^&*)");
        }
        return RootResponse.success();
    }


    // 处理用户数据
    private void handleUserData(CreateUserDTO createUserDTO, SysUser user, LoginUserDTO loginUserDTO) {
        BeanCopyUtils.copy(createUserDTO, user);
        user.setId(HandleUtils.UUID32());
        user.setCreateDateTime(new Date());
        user.setCreator(loginUserDTO.getUsername());
        user.setIsSoftDelete(false);
        var salt = HandleUtils.getRandomString(32);
        var str = new StringBuilder();
        str = str.append(createUserDTO.getPassword()).append(salt);
        var pSHA256 = SHA256Utils.SHA256(str.toString());
        user.setPassword(pSHA256);
        user.setSalt(salt);
    }

    @Override
    public RootResponse createUsersRoles(UserRoleDTO roleDTO, LoginUserDTO loginDTO) {
        var queryWrapper = new LambdaQueryWrapper<SysUser>();
        queryWrapper.eq(SysUser::getId, roleDTO.getUserId());
        queryWrapper.eq(SysUser::getIsSoftDelete, false);
        var sysUser = sysUserMapper.selectOne(queryWrapper);
        if (sysUser == null) {
            return RootResponse.error(CodeStatusEnum.NOT_EXIST_DATA);
        }
        // 先删除角色和权限的关联关系
        var wrapper = new LambdaQueryWrapper<SysUserRole>();
        wrapper.eq(SysUserRole::getUserId, roleDTO.getUserId());
        userRoleMapper.delete(wrapper);
        // 添加关联关系
        if (roleDTO.getRoleIds() != null && !roleDTO.getRoleIds().isEmpty()) {
            roleDTO.getRoleIds().forEach(m -> {
                var sysUserRole= new SysUserRole();
                sysUserRole.setId(HandleUtils.UUID32());
                sysUserRole.setCreator(loginDTO.getUsername());
                sysUserRole.setCreateDateTime(new Date());
                sysUserRole.setRoleId(m);
                sysUserRole.setIsSoftDelete(false);
                sysUserRole.setUserId(roleDTO.getUserId());
                int j=userRoleMapper.insert(sysUserRole);
                if (j != 1) {
                    throw new RuntimeException("给用户分配角色失败");
                }
            });
        }
        return RootResponse.success();
    }

    @Override
    public RootResponse queryUserRoles(String userId) {
        return RootResponse.success(sysUserMapper.selectRolesByUserIdV1(userId));
    }

    @Override
    public RootResponse selectSysMessages(SysMessagePageDTO teachDataTypePageDTO, LoginUserDTO userDTO) {
        PageHelper.startPage(teachDataTypePageDTO.getPageNum(), teachDataTypePageDTO.getPageSize());

        var sysMessages= sysMessageMapper.selectSysMessagesAll(userDTO.getUserId());
        var pageInfo = PageInfo.of(sysMessages);
        return RootResponse.success(PageResult.page(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal()));
    }

    @Override
    public RootResponse selectSysMessagesNotCount(LoginUserDTO userDTO) {
        var queryWrapper = new LambdaQueryWrapper<SysMessage>();
        queryWrapper.eq(SysMessage::getIsSoftDelete, false);
        return RootResponse.success(sysMessageMapper.selectSysMessagesNotCount(userDTO.getUserId()));
    }

    @Override
    public RootResponse selectSysMessagesSetRead(LoginUserDTO userDTO,String id) {
      var sysMessage=new  SysMessageProcess();
      sysMessage.setCreator(userDTO.getUsername());
        sysMessage.setCreateDateTime(new Date());
        sysMessage.setId(HandleUtils.UUID32());
      sysMessage.setIsSoftDelete(false);
        sysMessage.setRecipient(userDTO.getUserId());
        sysMessage.setMessageId(id);
        sysMessageProcessMapper.insert(sysMessage);
        return RootResponse.success("更新成功！！！");
    }

    @Override
    public RootResponse selectSysMessagesSetAllRead(LoginUserDTO userDTO) {
        sysMessageMapper.selectSysMessages(userDTO.getUserId()).forEach(id->{
            var sysMessage=new  SysMessageProcess();
            sysMessage.setCreator(userDTO.getUsername());
            sysMessage.setCreateDateTime(new Date());
            sysMessage.setId(HandleUtils.UUID32());
            sysMessage.setIsSoftDelete(false);
            sysMessage.setRecipient(userDTO.getUserId());
            sysMessage.setMessageId(id);
            sysMessageProcessMapper.insert(sysMessage);
        });
        return RootResponse.success("更新成功！！！");
    }
}
